#ifndef TIMERSERVICE_H
#define TIMERSERVICE_H

#include "core_global.h"
#include "deadlinetimerpool.h"
#include <boost/noncopyable.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/function.hpp>

class AsyncService;

class CORE_EXPORT TimerService :
        protected boost::noncopyable
{
public:
    typedef boost::asio::deadline_timer DeadlineTimer;
    typedef boost::system::error_code ErrorCode;
    typedef boost::mutex Mutex;

    typedef boost::shared_ptr< DeadlineTimer > TimerPtr;
    typedef boost::unordered_map< unsigned int, TimerPtr > TimerMap;
    typedef boost::shared_ptr< TimerMap > TimerMapPtr;
    typedef boost::unordered_map< unsigned int, TimerMapPtr > OwnerMap;
    typedef boost::unordered_set< TimerPtr > TimerSet;

    typedef boost::function< void (unsigned int, unsigned int, unsigned long msec, unsigned int) > Completion;

public:
    TimerService(AsyncService &service);
    ~TimerService();

    bool setTimer(unsigned int owner, unsigned int id,
                  unsigned long msec, unsigned int repeat,
                  BOOST_ASIO_MOVE_ARG(Completion) c);
    bool killTimer(unsigned int owner, unsigned int id);
    bool killTimer(unsigned int owner);

protected:
    void onTimer(Completion c, TimerPtr timer, void *reserve, ErrorCode ec);
    void onTrash();

private:
    AsyncService &m_service;

    DeadlineTimerPool m_pool;

    OwnerMap m_om;

    TimerSet m_trash;

    Mutex m_omLock;

    Mutex m_trashLock;
};

#endif // TIMERSERVICE_H
